﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using Lime49.WPF;
using LockCrypt.Core;

namespace LockCrypt {
    /// <summary>
    /// A group of accounts.
    /// </summary>
    public class Group : GroupBase, INotifyPropertyChanged {
        public override string ID { 
            get { return base.ID; }
            set { 
                base.ID = value;
                OnPropertyChanged("ID");
            }
        }
        public override string Name {
            get { return base.Name; }
            set {
                base.Name = value;
                OnPropertyChanged("Name");
            }
        }
        public override string Icon {
            get { return base.Icon; }
            set {
                base.Icon = value;
                OnPropertyChanged("Icon");
            }
        }
        public override IList<IGroup> Groups {
            get { return base.Groups; }
            set {
                base.Groups = value;
                OnPropertyChanged("Groups");
            }
        }
        public override IList<IAccount> Accounts {
            get { return base.Accounts; }
            set {
                base.Accounts = value;
                OnPropertyChanged("Accounts");
            }
        }
        public override string ParentID {
            get { return base.ParentID; }
            set {
                base.ParentID = value;
                OnPropertyChanged("ParentID");
            }
        }
        public override int SortIndex {
            get { return base.SortIndex; }
            set {
                base.SortIndex = value;
                OnPropertyChanged("SortIndex");
            }
        }

        /// <summary>
        /// Represents the root group
        /// </summary>
        public static readonly Group Empty = new Group() { 
            ID = null,
            Name = I18nUtils.GetString("Strings", "None"), 
            SortIndex = 0 
        };

        /// <summary>
        /// Initializes a new <see cref="Group"/>.
        /// </summary>
        public Group()
            : base() {
            Groups = new ObservableCollection<IGroup>();
            Accounts = new ObservableCollection<IAccount>();
        }

        /// <summary>
        /// Initializes a new <see cref="Group"/> from another group.
        /// </summary>
        /// <param name="group">The base group.</param>
        public Group(IGroup group)
            : this() {
            this.ID = group.ID;
            this.Name = group.Name;
            this.Icon = group.Icon;
            this.ParentID = group.ParentID;
            this.SortIndex = group.SortIndex;
            foreach(IGroup childGroup in group.Groups) {
                this.Groups.Add(new Group(childGroup));
            }
            foreach(IAccount account in group.Accounts) {
                this.Accounts.Add(new Account(account));
            }
        }

        /// <summary>
        /// Creates a deep copy of this group.
        /// </summary>
        /// <returns>A clone of this group.</returns>
        public override IGroup Clone() {
            Group clone = new Group() {
                ID = this.ID,
                Name = this.Name,
                Icon = this.Icon,
                ParentID = this.ParentID,
                SortIndex = this.SortIndex
            };
            foreach(IGroup childGroup in this.Groups) {
                clone.Groups.Add(childGroup.Clone());
            }
            foreach(IAccount account in this.Accounts) {
                clone.Accounts.Add(account.Clone());
            }
            return clone;
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(string strPropertyName) {
            if(PropertyChanged != null) {
                PropertyChanged(this, new PropertyChangedEventArgs(strPropertyName));
            }
        }
    }
}
